/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jard.webshop.management;

import jard.webshop.jsfbeans.CartModel;
import jard.webshop.util.FinancialException;
import jard.webshop.util.ProductException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import jard.webshop.management.CategoryManagement;
import jard.webshop.management.PreferencesManagement;
import jard.webshop.nbp.Address;
import jard.webshop.nbp.Category;
import jard.webshop.nbp.Invoice;
import jard.webshop.nbp.Order;
import jard.webshop.nbp.Product;
import jard.webshop.nbp.SitePref;
import jard.webshop.nbp.User;
import jard.webshop.util.Constants;
import jard.webshop.util.Utils;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
 * Web application lifecycle listener.
 * @author CJP
 */
@WebListener()
public class StartupManagement implements ServletContextListener {

    private static ProductManagement pm = null;
    private static CategoryManagement cm = null;
    private static UserManagement um = null;
    private static OrderManagement om = null;
    private static PreferencesManagement prm = null;

    @Override
    public void contextInitialized(ServletContextEvent sce) {

        Object webshopnameObj = sce.getServletContext().getInitParameter("jard.webshop.nbp.webshopname");
        String webshopname = "Default";
        if (webshopnameObj instanceof String) {
            webshopname = (String) webshopnameObj;
        }

        Object discriptionObj = sce.getServletContext().getInitParameter("jard.webshop.nbp.discription");
        String discription = "Default";
        if (discriptionObj instanceof String) {
            discription = (String) discriptionObj;
        }

        Object keywordsObj = sce.getServletContext().getInitParameter("jard.webshop.nbp.keywords");
        String keywords = "Default";
        if (keywordsObj instanceof String) {
            keywords = (String) keywordsObj;
        }

        Object authorObj = sce.getServletContext().getInitParameter("jard.webshop.nbp.author");
        String author = "Default";
        if (authorObj instanceof String) {
            author = (String) authorObj;
        }

        Object showAlertMessageObj = sce.getServletContext().getInitParameter("jard.webshop.nbp.showAlertMessage");
        String showAlertMessage = "false";
        if (showAlertMessageObj instanceof String) {
            showAlertMessage = (String) showAlertMessageObj;
        }

        Object alertMessageObj = sce.getServletContext().getInitParameter("jard.webshop.nbp.alertMessage");
        String alertMessage = "Default";
        if (alertMessageObj instanceof String) {
            alertMessage = (String) alertMessageObj;
        }

        Object siteOfflineObj = sce.getServletContext().getInitParameter("jard.webshop.nbp.siteOffline");
        String siteOffline = "false";
        if (siteOfflineObj instanceof String) {
            siteOffline = (String) siteOfflineObj;
        }

        Object offlineMessageObj = sce.getServletContext().getInitParameter("jard.webshop.nbp.offlineMessage");
        String offlineMessage = "Default";
        if (offlineMessageObj instanceof String) {
            offlineMessage = (String) offlineMessageObj;
        }

        SitePref sp = new SitePref();
        sp.setWebshopname(webshopname);
        sp.setDescription(discription);
        sp.setKeywords(keywords);
        sp.setAuthor(author);
        sp.setShowAlertMessage(Boolean.parseBoolean(showAlertMessage));
        sp.setAlertMessage(alertMessage);
        sp.setSiteOffline(Boolean.parseBoolean(siteOffline));
        sp.setOfflineMessage(offlineMessage);



        Object admObj = sce.getServletContext().getInitParameter("jard.webshop.nbp.AdminLevel");
        Integer admin_level = 4;
        if (admObj instanceof Integer) {
            admin_level = (Integer) admObj;
        }

        Constants.setAdminLevel(admin_level);

        Object empObj = sce.getServletContext().getInitParameter("jard.webshop.nbp.EmployeeLevel");
        Integer employee_level = 3;
        if (empObj instanceof Integer) {
            employee_level = (Integer) empObj;
        }

        Constants.setEmployeeLevel(employee_level);

        Object currObj = sce.getServletContext().getInitParameter("jard.webshop.nbp.Currency");
        String currency = "SEK";
        if (currObj instanceof String) {
            currency = (String) currency;
        }

        Constants.setCurrency(currency);

        EntityManagerFactory emf = Persistence.createEntityManagerFactory("jard_webshop_PU");
        CategoryManagement.setEntityManagerFactory(emf);
        cm = CategoryManagement.getInstance();
        ProductManagement.setEntityManagerFactory(emf);
        pm = ProductManagement.getInstance();
        UserManagement.setEntityManagerFactory(emf);
        um = UserManagement.getInstance();
        OrderManagement.setEntityManagerFactory(emf);
        om = OrderManagement.getInstance();

        //Add Preferences from web.xml to backing bean
        PreferencesManagement.setEntityManagerFactory(emf);
        prm = PreferencesManagement.getInstance();
        prm.addPreferences(sp);

        createCategories();
        createProducts();
        createUsers();
        createOrders();
    }

    @Override // Not needed but required by abstract superclass
    public void contextDestroyed(ServletContextEvent sce) {
    }

    private void createCategories() {
        Category demo = new Category("Clothes");
        Category sample1 = new Category("Shirts");
        Category sample2 = new Category("Pants");
        Category sample3 = new Category("Hats");
        demo.addSubcategory(sample1);
        demo.addSubcategory(sample2);
        demo.addSubcategory(sample3);
        cm.addCategory(demo);

        Category demo2 = new Category("Shoes");
        Category sample21 = new Category("Boots");
        Category sample211 = new Category("Hiking boots");
        Category sample212 = new Category("Cowboy boots");
        Category sample22 = new Category("Sneakers");
        Category sample23 = new Category("Loafers");
        demo2.addSubcategory(sample21);
        sample21.addSubcategory(sample211);
        sample21.addSubcategory(sample212);
        demo2.addSubcategory(sample22);
        demo2.addSubcategory(sample23);
        cm.addCategory(demo2);
    }

    private void createProducts() {
        createProduct("Zombie T-shirt");
        createProduct("Zombie Pants");
    }

    private void createProduct(String productName) {
        List<String> colors = new ArrayList<String>(5);
        colors.add("Night-black");
        colors.add("Zombie-green");
        colors.add("Blood-red");
        colors.add("Brain-pink");
        colors.add("Pale-yellow");

        List<Category> categories = cm.getCategoriesByName("Clothes");

        List<Product> productList = new ArrayList<Product>(5);
        for (String a : colors) {
            Product p = new Product(productName, "Zombies inc.", categories.get(0), 100.0f);
            p.setStock(100);
            p.setAttr1(a);
            p.setVisible(false);
            productList.add(p);
        }
        Boolean flip = true;
        Product product = null;
        for (Product p : productList) {
            if (flip) {
                product = p;
                product.setVisible(true);
                flip = false;
                product.addGroupedWith(p); // <-- Why is evident in product.xhtml
            } else {
                product.addGroupedWith(p);
            }
        }

        pm.addProduct(product);
    }

    private void createUsers() {
        Address jAddr = new Address("Street 19", 23457, "Göteborg");
        User j = new User("johan@cth.com", Utils.hash("johan"));
        j.setName("Johan");
        j.setAddress(jAddr);
        j.setAuthLevel(Constants.getAdminLevel());

        Address rAddr = new Address("Street 1", 23455, "Göteborg");
        User r = new User("roger@cth.com", Utils.hash("roger"));
        r.setName("Roger");
        r.setAddress(rAddr);
        r.setAuthLevel(Constants.getEmployeeLevel()); // To test the differences

        Address aAddr = new Address("Street 2", 13457, "Göteborg");
        User a = new User("andreas@cth.com", Utils.hash("andreas"));
        a.setName("Andreas");
        a.setAddress(aAddr);

        Address dAddr = new Address("Street 3", 33457, "Göteborg");
        User d = new User("disa@cth.com", Utils.hash("disa"));
        d.setName("Disa");
        d.setAddress(dAddr);
        d.setNewsLetter(true);

        um.addUser(j);
        um.addUser(r);
        um.addUser(a);
        um.addUser(d);
    }

    private void createOrders() {

        List<User> buyers = new ArrayList<User>();
        buyers.add(um.getUser("johan@cth.com"));
        buyers.add(um.getUser("roger@cth.com"));
        buyers.add(um.getUser("andreas@cth.com"));
        buyers.add(um.getUser("disa@cth.com"));

        // Let's buy some products and pay for them
        Product toBuy = pm.getProductsByName("Zombie T-Shirt").get(0);
        for (User u : buyers) {
            CartModel cart = new CartModel();
            cart.addProduct(toBuy);
            cart.addProduct(toBuy);

            try {
                Order ord = om.addOrder(u, cart);
                Invoice invoice = ord.getInvoice();
                Float installmentAmount = invoice.getTotalAmount() / 2;
                om.registerPayment(invoice, installmentAmount);
                om.registerPayment(invoice, installmentAmount);
            } catch (FinancialException ex) {
                System.err.println("Oh, dear. I couldn't buy a Zombie T-shirt for financial reasons.");
            } catch (ProductException ex) {
                System.err.println("Oh, dear. I couldn't buy a Zombie T-shirt for product reasons.");
            }
        }

        // Now for some unpaid bills as well
        for (User u : buyers) {
            CartModel cart = new CartModel();
            cart.addProduct(toBuy);
            cart.addProduct(toBuy);
            cart.addProduct(toBuy);

            try {
                Order ord = om.addOrder(u, cart);
                Invoice invoice = ord.getInvoice();
                Float installmentAmount = invoice.getTotalAmount() / 3;
                om.registerPayment(invoice, installmentAmount);
            } catch (FinancialException ex) {
                System.err.println("Oh, dear. I couldn't buy a Zombie T-shirt for financial reasons.");
            } catch (ProductException ex) {
                System.err.println("Oh, dear. I couldn't buy a Zombie T-shirt for product reasons.");
            }
        }
    }
}
